﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace Recipes.Upsert
{
    /// <summary>
    /// This scenario performs basic CRUD operations on a simple model without children.
    /// </summary>
    /// <typeparam name="TModel">A EmployeeClassification model or entity</typeparam>
    [TestCategory("Upsert")]
    public abstract class UpsertTests<TDivision>
       where TDivision : class, IDivision, new()
    {
        [TestMethod]
        public void UpsertByName()
        {
            var repository = GetScenario();
            var original = new TDivision()
            {
                DivisionName = "Test " + DateTime.Now.Ticks,
                MaxEmployees = 1,
                CreatedByEmployeeKey = 1,
                ModifiedByEmployeeKey = 1
            };
            var newKey = repository.UpsertByName(original);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var echo = repository.GetByKey(newKey);
            Assert.IsNotNull(echo); 
            Assert.AreEqual(newKey, echo.DivisionKey);
            Assert.AreEqual(original.DivisionName, echo.DivisionName);
            Assert.AreEqual(original.MaxEmployees, echo.MaxEmployees);
            Assert.AreEqual(original.CreatedByEmployeeKey, echo.CreatedByEmployeeKey);
            Assert.AreEqual(original.ModifiedByEmployeeKey, echo.ModifiedByEmployeeKey);

            var updater = new TDivision()
            {
                DivisionName = original.DivisionName,
                MaxEmployees = 2,
                CreatedByEmployeeKey = 1,
                ModifiedByEmployeeKey = 2
            };
            var newKey2 = repository.UpsertByName(updater);
            Assert.AreEqual(newKey, newKey2);

            var echo2 = repository.GetByKey(newKey);
            Assert.IsNotNull(echo2);
            Assert.AreEqual(newKey, echo2.DivisionKey);
            Assert.AreEqual(updater.DivisionName, echo2.DivisionName);
            Assert.AreEqual(updater.MaxEmployees, echo2.MaxEmployees);
            Assert.AreEqual(updater.CreatedByEmployeeKey, echo2.CreatedByEmployeeKey);
            Assert.AreEqual(updater.ModifiedByEmployeeKey, echo2.ModifiedByEmployeeKey);
        }

        [TestMethod]
        public void UpsertByPrimaryKey()
        {
            var repository = GetScenario();
            var original = new TDivision()
            {
                DivisionName = "Test " + DateTime.Now.Ticks,
                MaxEmployees = 1,
                CreatedByEmployeeKey = 1,
                ModifiedByEmployeeKey = 1
            };
            var newKey = repository.UpsertByPrimaryKey(original);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var echo = repository.GetByKey(newKey);
            Assert.IsNotNull(echo);
            Assert.AreEqual(newKey, echo.DivisionKey);
            Assert.AreEqual(original.DivisionName, echo.DivisionName);
            Assert.AreEqual(original.MaxEmployees, echo.MaxEmployees);
            Assert.AreEqual(original.CreatedByEmployeeKey, echo.CreatedByEmployeeKey);
            Assert.AreEqual(original.ModifiedByEmployeeKey, echo.ModifiedByEmployeeKey);

            var updater = new TDivision()
            {
                DivisionKey = newKey,
                DivisionName = "Test " + DateTime.Now.Ticks,
                MaxEmployees = 2,
                CreatedByEmployeeKey = 1,
                ModifiedByEmployeeKey = 2
            };
            var newKey2 = repository.UpsertByPrimaryKey(updater);
            Assert.AreEqual(newKey, newKey2);

            var echo2 = repository.GetByKey(newKey);
            Assert.IsNotNull(echo2); 
            Assert.AreEqual(newKey, echo2.DivisionKey);
            Assert.AreEqual(updater.DivisionName, echo2.DivisionName);
            Assert.AreEqual(updater.MaxEmployees, echo2.MaxEmployees);
            Assert.AreEqual(updater.CreatedByEmployeeKey, echo2.CreatedByEmployeeKey);
            Assert.AreEqual(updater.ModifiedByEmployeeKey, echo2.ModifiedByEmployeeKey);
        }

        protected abstract IUpsertScenario<TDivision> GetScenario();
    }
}
